/*
 *
 * scumix.swat.spark.ActiveTree
 * 交互树组件
 *
 * author: scumyang
 * create: 2012-12-31
 * notes : 需导入 scumix.swat.swat3.js
 * update:
 *			2013-01-15: +ActiveTreeList.clear(), 清空树.
 *
 */

scumix.swat.spark.TreeItem = $.newClass();
scumix.swat.spark.TreeItem.prototype =
{
	constructor: function( P )
	{
		this.id = P.id || $.makeGlobalId( 'SxTreeItem' );
		this.index = 0;
		this.absIndex = 0;
		this.level = P.level || 0;
		this.text = P.text || 'NODE';
		this.status = 0;
		this.checked = P.checked || 0;
		this.nodeIcon = P.nodeIcon || 'assets/images/icon-1045.gif';

		this.rootCompInstance = P.rootCompInstance;
		this.parentObject = P.parentObject;
		this.elemFrame = 0;
		this.elemLine = 0;
		this.elemContent = 0;
		this.elemCtrlIcon = 0;
		this.elemCheck = 0;
		this.elemIcon = 0;
		this.elemText = 0;
		this.elemREdge = 0;

		this.doCreate( P );
	},

	doCreate: function( P )
	{
		with( this )
		{
			elemFrame = $.createElement( {type:'div', id:id, css:'border2:1px solid #c00;width:100%', attr:{xJsObject:this, className:'SxActiveTree_Item'}} );
			elemLine = $.createElement( {type:'div', id:id + '_Line', css:'border2:1px solid #c00;width:100%', attr:{xJsObject:this, className:'line'}} );
				$(elemLine)
					.css('width', rootCompInstance.width - 3)
					.event('mouseover', function()
					{
						with( this )
						{
							if( xJsObject != xJsObject.rootCompInstance.curItem )
							{
								className = 'lineH';
								xJsObject.elemREdge.className = 'REdgeH';
							}
						}
					})
					.event('mouseout', function()
					{
						with( this )
						{
							if( xJsObject == xJsObject.rootCompInstance.curItem )
							{
								className = 'lineSelected';
								xJsObject.elemREdge.className = 'REdgeSelected';
							}
							else
							{
								elemLine.className = 'line';
								xJsObject.elemREdge.className = 'REdge';
							}
						}
					})
					.event('mousedown', function()
					{
						with( this.xJsObject )
						{
							if( level == 0 ) return;
							var e = $.getTarget();
							if( e.xGroup == 'checkbox' || e.xGroup == 'ctrlIcon' ) return;
							setCurItem( this.xJsObject );
							if( rootCompInstance.dragable )	rootCompInstance.isDragging = 1;
							//$(this.xJsObject.rootCompInstance.elemLine).css('cursor', 'move');
						}
					})
					.event('mouseup', function()
					{
						with( this.xJsObject )
						{
							if( rootCompInstance.isDragging )
							{
								rootCompInstance.isDragging = 0;
								$(rootCompInstance.elemHotItem).hide();

								if( rootCompInstance.curItem == this.xJsObject || this.xJsObject == rootCompInstance.curItem.parentObject || isChildOf( rootCompInstance.curItem )) return;
								moveItem( rootCompInstance.curItem, this.xJsObject );
							}
						}
					})
					.event('mousemove', function()
					{
						with( this.xJsObject )
						{
							if( rootCompInstance.isDragging )
							{
								var E = $.getEvent();
								$(rootCompInstance.elemHotItem).show().css('left', E.clientX ).css('top', E.clientY - $(rootCompInstance.elemFrame).absPos().top + 24);
								//$(rootCompInstance.elemHotItem).show().css('left', E.clientX ).css('top', E.clientY + 24);

								if( rootCompInstance.curItem == this.xJsObject || this.xJsObject == rootCompInstance.curItem.parentObject || isChildOf( rootCompInstance.curItem ))
								{
									rootCompInstance.elemHotItem.innerHTML = '不能移动到这里';
									//$(rootCompInstance.elemHotItem).hide();
									return;
								}

								rootCompInstance.elemHotItem.innerHTML = '移动: ' + rootCompInstance.curItem.text + '(level:' + rootCompInstance.curItem.level + ') 到 ' + text + '(level:' + level + ')';

								/*if( E.clientY > 20 )
									rootCompInstance.elemHotItem.innerHTML = '更改顺序: ' + rootCompInstance.curItem.text + '(level:' + rootCompInstance.curItem.level + ') 到 ' + text + '(level:' + level + ') 之后';
								else
									rootCompInstance.elemHotItem.innerHTML = '移动节点: ' + rootCompInstance.curItem.text + '(level:' + rootCompInstance.curItem.level + ') 到 ' + text + '(level:' + level + ')';
									*/
							}
						}
					})
					.event('click', function()
					{
						var e = $.getTarget();
						if( e.xGroup == 'checkbox' || e.xGroup == 'ctrlIcon' ) return;
						with( this )
						{
							xJsObject.setCurItem( xJsObject );
							if( xJsObject.rootCompInstance.onClick ) xJsObject.rootCompInstance.onClick( xJsObject );
						}
					})
					.event('dblclick', function()
					{
						var e = $.getTarget();
						if( e.xGroup == 'checkbox' || e.xGroup == 'ctrlIcon' ) return;
						this.xJsObject.status == 0 ? this.xJsObject.expand() : this.xJsObject.collapse();
					})
					;
				elemFrame.appendChild( elemLine );

			elemCtrlIcon = $.createElement( {type:'div', id:id + '_CtrlIcon', css:'', attr:{xJsObject:this, xGroup:'ctrlIcon', className:'CI_Close'}} )
				elemCtrlIcon.style.marginLeft = level * 20;
				$(elemCtrlIcon)
					.css('visibility', 'hidden')
					.event('mouseover', function()
					{
						with( this )
						{
							className = ( xJsObject.status == 0 ) ? 'CI_CloseH' : 'CI_OpenH';
						}
					})
					.event('mouseout', function()
					{
						with( this )
						{
							className = ( xJsObject.status == 0 ) ? 'CI_Close' : 'CI_Open';
						}
					})
					.event('mousedown', function()
					{
						with( this )
						{
							xJsObject.status == 0 ? xJsObject.expand() : xJsObject.collapse();
						}
					})
					;

			elemCheck = $.createElement( {type:'input', id:id + '_Check', css:'margin:0px', attr:{xJsObject:this, xGroup:'checkbox', className:'checkbox', type:'checkbox'}} );
				if( !rootCompInstance.showCheckbox ) $(elemCheck).hide();
				$(elemCheck)
					.event('click', function()
					{
						with( this )
						{
							if( xJsObject.absIndex == 0 ) xJsObject.setChecked( checked, -1 );
							xJsObject.setChecked( checked );
						}
					})
					;

			elemIcon = $.createElement( {type:'div', id:id + '_Icon', css:'', attr:{xJsObject:this, className:'nodeIcon'}} );
				elemIcon.style.background = 'url(' + nodeIcon + ') no-repeat center';
				if( !rootCompInstance.showNodeIcon ) $(elemIcon).hide();

			elemText = $.createElement( {type:'div', id:id + '_Text', css:'border2:1px solid #c00', attr:{xJsObject:this, className:'text'}} );
			elemText.innerHTML = text;
				$(elemText)
					.event('click', function()
					{
					})
					;

			elemREdge = $.createElement( {type:'div', id:id + '_REdge', css:'float:right', attr:{xJsObject:this, className:'REdge'}} );

			elemLine.appendChild( elemCtrlIcon );
			elemLine.appendChild( elemCheck );
			elemLine.appendChild( elemIcon );
			elemLine.appendChild( elemText );
			elemFrame.appendChild( elemREdge );

			elemContent = $.createElement( {type:'div', id:id + '_Content', css:'border2:1px solid #00c', attr:{xJsObject:this, className:'content'}} );
				$(elemContent).hide();
				elemFrame.appendChild( elemContent );

			if( parentObject ) parentObject.elemContent.appendChild( elemFrame );
		}
	},

	addItem: function( P, __expand )
	{
		with( this )
		{
			var item = new scumix.swat.spark.TreeItem( { rootCompInstance:rootCompInstance, parentObject:this, id:P.id, text:P.text, level:level+1} );
			appendItem( item, __expand || P.autoExpand );
		}

		return item;
	},

	moveItem: function( src, dst )
	{
		//$ERR( 'BEGIN src='+src.text + '(' + src.level + '), dst=' + dst.text + '(' + dst.level + ')' );
		//$E('eINFO').innerHTML = '';
		//$ERR( 'moveItem: src=' + src.text + ' dst=' + dst.text );
		dst.appendItem( src.removeItem(), 1 );
		//$ERR( 'END src='+src.text + '(' + src.level + '), dst=' + dst.text + '(' + dst.level + ')' );
		//$ERR('-----');
	},

	// 添加节点条目
	appendItem: function( O, __expand )
	{
		with( this )
		{
			if( !O ) alert( 'appendItem(): 添加节点失败, 节点对象不存在' );
			else
			{
				// 定位节点, 默认为末尾子节点, 无子节点则为当前节点之后
				var childNode = getChild('last') || this;

				// 插入数组的起始位置 = 定位节点索引 + 其全部子节点数 + 1
				var startAbsIdx = childNode.absIndex + childNode.getChildNum() + 1;

				//$ERR('appendItem(): -> '+childNode.text + ' this=' + this.text + ', O.abs=' + O.absIndex + ', targetAbs=' + absIndex );

				// 若传入数组, 需遍历插入其元素
				if( $.isArray(O))
				{
					//rootCompInstance.printItems(1);

					// 更新新节点数组层级(=定位节点层级+1)
					updateLevel( O, level + 1 );

					for( var i=0; i<O.length; i++ )
					{
						rootCompInstance.items.splice( startAbsIdx + i, 0, O[i] );
						//$ERR( '> insert #' + i + ': ' + O[i].text );
					}

					//rootCompInstance.printItems(1);

					// 异常情况(数组读写错误导致绝对索引不匹配)
					if( this != rootCompInstance.items[this.absIndex] )
					{
						alert( 'appendItem(): absIndex not match: ' + this.text + ' -> ' + rootCompInstance.items[this.absIndex].text );
					}

					// 重排绝对索引
					rootCompInstance.resetAbsIndex();

					// 将相对根元素(新数组首元素)插入 DOM
					elemContent.appendChild( O[0].elemFrame );
					//$ERR( '-appendChild: ' + O[0].text + ' -> ' + this.text + ' lvl=' + this.level );
					O[0].parentObject = this;
					//$ERR( '-setParent: ' + O[0].text + ' -> ' + this.text + ' lvl=' + this.level );
					//rootCompInstance.printItems();

					rootCompInstance.repaint();
				}

				// 单个节点对象
				else
				{
					rootCompInstance.items.splice( startAbsIdx, 0, O );
					rootCompInstance.resetAbsIndex();

					elemContent.appendChild( O.elemFrame );
					O.parentObject = this;
					O.level = level + 1;

					rootCompInstance.repaint();
				}

				// 插入后是否自动展开节点
				if( __expand ) expand();
			}
		}

		return this;
	},

	// 删除节点条目
	// O: 要删除的子节点对象, 为空表示删除自身
	removeItem: function( O )
	{
		with( this )
		{
			O = O || this;

			// 不允许删除根节点
			if( O.parentObject == null || O.parentObject == rootCompInstance ) return false;

			// 删除对象(包括其子节点)
			//$ERR( 'removeItem: abs=' + O.absIndex + ', text=' + O.text + ', child=' + (O.getChildNum() + 1) + ' from ' + text );
			var arr = rootCompInstance.items.splice( O.absIndex, O.getChildNum() + 1 );

			// 删除关联 DOM 元素
			O == this ? O.parentObject.elemContent.removeChild( O.elemFrame ) : elemContent.removeChild( O.elemFrame );

			// 重排序, 重绘
			rootCompInstance.resetAbsIndex().repaint();

			// 返回删掉的对象数组(用于 moveItem 操作)
			return arr;
		}
	},

	// 更新节点层级
	// O: 节点对象数组
	// N: 指定的层级
	updateLevel: function( O, N )
	{
		//$ERR( "updateLevel(): Olen=" + O.length + ", N=" + N );

		// 计算出目标层级差值
		var D = N - O[0].level;
		for( var i=0; i<O.length; i++ )
		{
			//$ERR('>#'+i+ ': ' + O[i].text + ', (p=' + O[i].parentObject.text + ') lvl: ' + O[i].level + '->' + (O[i].level + D));
			O[i].level += D;
		}

		return this;
	},

	// 取当前节点的子节点对象
	// A: 位置
	//		first: 取首个子节点
	//		last : (默认)取末尾子节点
	// 返回: null 表示无子节点, 其他值为找到的子节点
	getChild: function( A )
	{
		with( this )
		{
			A = A || 'last';
			for( var i = absIndex + 1; i<=rootCompInstance.items.length; i++ )
			{
				// 若已超出数组总长, 或节点层级不大于当前节点层级, 则返回
				if( !rootCompInstance.items[i] || rootCompInstance.items[i].level <= level || rootCompInstance.items[i].level > level + 1 )
				{
					// 超出部长返回 null, 否则将上一个节点作为末尾子节点返回
					return i > absIndex + 1 ? rootCompInstance.items[i-1] : null;
				}

				// 若指定 first, 则立即返回该节点
				if( A == 'first' ) return rootCompInstance.items[i];
			}
		}
	},

	// 取子节点数
	// A: 需遍历的子目录级数, 默认为全部
	getChildNum: function( A )
	{
		with( this )
		{
			for( var i = absIndex + 1; i<=rootCompInstance.items.length; i++ )
			{
				if( rootCompInstance.items[i] == undefined || rootCompInstance.items[i].level <= level )
				{
					return i - ( absIndex + 1 );
				}
			}

			return 0;
		}
	},

	// 取子节点集合
	// A: 需遍历的子目录级数, 默认为全部
	getChildItem: function( A )
	{
		with( this )
		{
			var arr = [];
			for( var i = absIndex + 1; i<=rootCompInstance.items.length; i++ )
			{
				if( rootCompInstance.items[i] == undefined || rootCompInstance.items[i].level <= level ) break;
				if( A > 0 && rootCompInstance.items[i].level > level + A ) continue;
				arr.push( rootCompInstance.items[i] );
			}

			return arr;
		}
	},

	// 按属性取节点
	getChildByProperty: function( P, V )
	{
		with( this.rootCompInstance )
		{
			for( var i=0; i<items.length; i++ )
			{
				if( items[i][P] && items[i][P] == V ) return items[i];
			}

			return null;
		}
	},

	// 判断当前节点是否是指定节点的子节点
	// O: 目标节点
	isChildOf: function( O )
	{
		with( this )
		{
			var p = parentObject;
			while( p )
			{
				if( p == O ) return true;
				p = p.parentObject;
			}
			return false;
		}
	},

	// 重绘节点
	repaint: function()
	{
		with( this )
		{
			// 根据层级决定向右偏移
			// 根据子节点数决定是否显示折叠图标
			$(elemCtrlIcon)
				.css('marginLeft', level * 20 )
				.visible( getChildNum() )
				;

			/*
			var arr = getChildItem(1);
			var arrS = '';
			for( var i in arr ) arrS += arr[i].text + '|';
			$(elemText).text( text + '(abs=' + absIndex + ', level=' + level + ', child=' + getChildNum() + ', parent=' + (parentObject ? parentObject.text : '{ROOT}') + ')' + arrS );
			*/
		}
	},

	// 设置选择状态
	// A: 是否选中
	// R: 同时选中的字节点层数
	setChecked: function( A, N )
	{
		with( this )
		{
			checked = A;
			elemCheck.checked = A;

			if( N )
			{
				var arr = getChildItem( N );
				for( var i in arr )
				{
					arr[i].setChecked( A );
				}
			}
		}

		return this;
	},

	// 设置当前条目
	setCurItem: function( A )
	{
		with( this )
		{
			if(!A) {alert('null obj'); return;}
			if( rootCompInstance.curItem )
			{
				rootCompInstance.curItem.elemLine.className = 'line';
				rootCompInstance.curItem.elemREdge.className = 'REdge';
			}

			rootCompInstance.curItem = A;
			A.elemLine.className = 'lineSelected';
			A.elemREdge.className = 'REdgeSelected';
		}

		return this;
	},

	// 展开节点
	expand: function()
	{
		with( this )
		{
			if( getChildNum() )
			{
				status = 1;
				var e = $.getTarget();
				elemCtrlIcon.className = ( e == this.elemCtrlIcon ) ? 'CI_OpenH' : 'CI_Open';
				$(elemContent).show();
			}
		}

		return this;
	},

	// 折叠节点
	collapse: function()
	{
		with( this )
		{
			//if( getChildNum() )
			{
				status = 0;
				elemCtrlIcon.className = 'CI_CloseH';
				$(elemContent).hide();
			}
		}

		return this;
	}
}

scumix.swat.spark.ActiveTreeList = $.newClass();
scumix.swat.spark.ActiveTreeList.prototype =
{
	constructor: function( P )
	{
		this.id = P.id || $.makeGlobalId( 'SxActiveTreeList' );
		this.animSpeed = P ? $.defaultValue( P.animSpeed , 1 ) : 1;
		this.rootItem = 0;
		this.text = P.text || this.id;

		this.items = new Array();
		this.curItem = 0;

		this.showCheckbox = P.showCheckbox || 1;
		this.showNodeIcon = P.showNodeIcon || 1;
		this.dragable = P.dragable || 1;
		this.isDragging = 0;
		this.width = 0;
		this.height = 0;

		// 事件
		this.onClick = P.onClick || 0;

		this.elemFrame = $E(P.container);
		if( !this.elemFrame )
		{
			alert( 'Class: scumix.swat.spark.ActiveTreeList\nError: 指定的容器无效: \'' + P.container + '\'' );
			return null;
		}

		this.elemContent = 0;
		this.elemHotItem = 0;

		this.doCreate( P );
	},

	doCreate: function( P )
	{
		with( this )
		{
			width = $(elemFrame).css('width');

			elemContent = $.createElement( {type:'div', id:id + '_Content', css:'border2:1px solid #0f0;height2:80px', attr:{xJsObject:this, className:''}} );
				elemFrame.appendChild( elemContent );

			rootItem = new scumix.swat.spark.TreeItem( { rootCompInstance:this, parentObject:null, id:id+'_Root', text:text} );
			rootItem.absIndex = 0;
			items[0] = rootItem;
			elemContent.appendChild( rootItem.elemFrame );

			elemHotItem = $.createElement( {type:'div', id:id + '_HotItem', css:'', attr:{xJsObject:this, className:'SxActiveTree_HotItem', xPass:1}} );
				$(elemHotItem).css('opacity', 60).hide();
			elemFrame.appendChild( elemHotItem );
		}
	},

	resetAbsIndex: function()
	{
		with( this )
		{
			for( var i=0; i<items.length; i++ )
			{
				items[i].absIndex = i;
			}
		}

		return this;
	},

	repaint: function()
	{
		with( this )
		{
			for( var i=0; i<items.length; i++ )
			{
				items[i].repaint();
			}
		}

		return this;
	},

	addItem: function( P, CI )
	{
		with( this )
		{
			CI = CI || curItem || rootItem;
			P.rootCompInstance = this;
			P.parentObject = rootItem;
			var n = CI.addItem( P );
			resetAbsIndex();
			n.repaint();
		}

		return this;
	},

	// 清空树
	clear: function()
	{
		with( this )
		{
			/*var n = items.length - 1;
			for( var i=0; i<n; i++ )
			{
				rootItem.removeItem( items[1] );
			}*/
			for( var i=1; i<items.length; i++ )
			{
				$.removeElement( items[i].elemFrame );
			}
			
			items.length = 1;
			rootItem.repaint();
		}

		return this;
	},

	getCheckedItems: function( A )
	{
		with( this )
		{
			var arr = [];
			for( var i=0; i<items.length; i++ )
			{
				if( items[i].checked ) arr.push( items[i] );
			}

			return arr;
		}
	},

	printItems: function( A )
	{
		with( this )
		{
			for( var i=0; i<items.length; i++ )
			{
				var p = items[i].parentObject;
				if( !p ) p = items[0];
				var s = '#' + i + ': ' + items[i].text + ', abs=' + items[i].absIndex + ', lvl=' + items[i].level + ', parent:' + p.text + ', lvl=' + p.level;
				if( items[i].level - p.level > 1 ){ s += ' (lvl invalid)'; if(!A)alert('lvl invalid');}
				if( items[i].absIndex !=i ) { s += ' (abs invalid)'; if(!A)alert('abs invalid');}
				$ERR( s );
			}
		}
	}
}